package com.wanwu.channel.service.strategy.parse;


import com.wanwu.channel.common.enums.ExceptionEnum;
import com.wanwu.channel.common.exception.SystemException;
import com.wanwu.channel.common.util.TrueFalse;
import com.wanwu.channel.common.util.UtilDate;
import com.wanwu.channel.common.util.XmlUtil;
import com.wanwu.channel.common.enums.AlipayAppErrorCodeEnums;
import com.wanwu.channel.service.strategy.domain.CustomsDeclare;
import com.wanwu.channel.service.strategy.domain.QueryApplyClearanceStrategyResponse;
import com.wanwu.channel.remote.alipay.util.AlipayNotify;
import org.jdom.JDOMException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.*;

public class AlipayParse {

    private static Logger logger = LoggerFactory.getLogger(AlipayParse.class);

    /**
     * 解析支付宝查询接口的同步返回
     *
     * @param response 同步返回的字符串
     * @return map
     * @throws JDOMException
     * @throws IOException
     */
    public static Map<String, String> doAlipayQueryReturnParse(String response, String pid, String alipayPublicKey,
                                                               String inputCharset){
        logger.info("解析支付宝查询接口，返回数据：{}", response);
        Map<String, String> resultMap = new TreeMap<>();
        Map map = XmlUtil.doAlipayQueryXMLParse(response);
        String isSuccess = (String) map.get("is_success");
        if (TrueFalse.T.equalsIgnoreCase(isSuccess)) {
            Map<String, Object> map1 = (Map<String, Object>) map.get("response");
            Map<String, Object> map2 = (Map<String, Object>) map1.get("trade");
            Map<String, String> map3 = new HashMap<>();
            map2.forEach((k, v) -> {
                map3.put(k, (String) v);
            });
            map3.put("sign", (String) map.get("sign"));
            map3.put("sign_type", (String) map.get("sign_type"));
//            boolean verifyResult = AlipayNotify.verify(map3, pid, alipayPublicKey, inputCharset);
            boolean verifyResult = Boolean.TRUE;
            if (verifyResult) {
                resultMap.putAll(map3);
            }
        }
        if (TrueFalse.F.equalsIgnoreCase(isSuccess)) {
            String errorCode = (String) map.get("error");
            resultMap.put("error_code", errorCode);
            resultMap.put("error_msg", AlipayAppErrorCodeEnums.getErrorCodeEnum(errorCode).getDesc());
        }
        resultMap.put("is_success", isSuccess);
        return resultMap;
    }

    /**
     * 解析支付宝申请报关的同步返回
     *
     * @param response
     * @param pid
     * @param alipayPublicKey
     * @param inputCharset
     * @return
     * @throws JDOMException
     * @throws IOException
     */
    public static Map<String, String> doAlipayApplyClearanceReturnParse(String response, String pid, String alipayPublicKey,
                                                                        String inputCharset) throws JDOMException, IOException {
        logger.info("解析支付宝申请报关接口，返回数据：{}", response);
        Map<String, String> resultMap = new TreeMap<>();
        Map map = XmlUtil.doAlipayQueryXMLParse(response);
        String isSuccess = (String) map.get("is_success");
        if (TrueFalse.T.equalsIgnoreCase(isSuccess)) {
            Map<String, Object> map1 = (Map<String, Object>) map.get("response");
            Map<String, Object> map2 = (Map<String, Object>) map1.get("alipay");
            Map<String, String> map3 = new HashMap<>();
            map2.forEach((k, v) -> {
                map3.put(k, (String) v);
            });
            map3.put("sign", (String) map.get("sign"));
            map3.put("sign_type", (String) map.get("sign_type"));
            boolean verifyResult = AlipayNotify.verify(map3, alipayPublicKey);
            if (verifyResult) {
                resultMap.putAll(map3);
            }

        }
        if (TrueFalse.F.equalsIgnoreCase(isSuccess)) {
            String errorCode = (String) map.get("error");
            resultMap.put("error_code", errorCode);
            resultMap.put("error_msg", AlipayAppErrorCodeEnums.getErrorCodeEnum(errorCode).getDesc());
        }
        resultMap.put("is_success", isSuccess);
        return resultMap;
    }

    /**
     * 解析支付宝申请报关的同步返回
     *
     * @param response
     * @param thirdDecPriKey
     * @return
     * @throws JDOMException
     * @throws IOException
     */
    public static Map<String, String> doAlipayApplyClearanceReturnParse(String response, String thirdDecPriKey) throws Exception {
        //logger.info("解析支付宝申请报关接口，返回数据：{}", response);
        Map<String, String> resultMap = new TreeMap<>();
        Map map = XmlUtil.doAlipayQueryXMLParse(response);
        String isSuccess = (String) map.get("is_success");
        if (TrueFalse.T.equalsIgnoreCase(isSuccess)) {
            Map<String, Object> map1 = (Map<String, Object>) map.get("response");
            Map<String, Object> map2 = (Map<String, Object>) map1.get("alipay");
            Map<String, String> map3 = new HashMap<>();
            map2.forEach((k, v) -> {
                map3.put(k, (String) v);
            });
            map3.put("sign", (String) map.get("sign"));
            map3.put("sign_type", (String) map.get("sign_type"));
            boolean verifyResult = AlipayNotify.verify(map3, thirdDecPriKey);
            if (verifyResult) {
                resultMap.putAll(map3);
            }else {
                logger.info("支付宝申请报关接口验签失败，返回数据：{}", response);
                throw new SystemException(ExceptionEnum.E20004);
            }

        }
        if (TrueFalse.F.equalsIgnoreCase(isSuccess)) {
            logger.info("支付宝申请报关接口返回失败，返回数据：{}", response);
            String errorCode = (String) map.get("error");
            resultMap.put("error_code", errorCode);
            resultMap.put("error_msg", AlipayAppErrorCodeEnums.getErrorCodeEnum(errorCode).getDesc());
        }
        resultMap.put("is_success", isSuccess);
        return resultMap;
    }

    /**
     * 解析支付宝查询报关的同步返回
     *
     * @param response
     * @param pid
     * @param alipayPublicKey
     * @param inputCharset
     * @return
     * @throws JDOMException
     * @throws IOException
     */
    public static QueryApplyClearanceStrategyResponse doAlipayQueryClearanceReturnParse(String response, String pid, String alipayPublicKey,
                                                                                        String inputCharset) throws JDOMException, IOException {
        logger.info("解析支付宝查询报关接口，返回数据：{}", response);
//        Map<String, Object> resultMap = new HashMap<>();
        Map map = XmlUtil.doAlipayQueryClearanceXMLParse(response);

        QueryApplyClearanceStrategyResponse result = new QueryApplyClearanceStrategyResponse();

        String isSuccess = (String) map.get("is_success");
        if (TrueFalse.T.equalsIgnoreCase(isSuccess)) {
            result.setSuccess(Boolean.TRUE);
            Map<String, Object> map1 = (Map<String, Object>) map.get("response");
            List<Map<String, Object>> list = (List<Map<String, Object>>) map1.get("alipay");
            list.forEach(i -> {
                String resultCode = (String) i.get("result_code");
//                resultMap.put("result_code", resultCode);
                if (TrueFalse.UPPER_SUCCESS.equals(resultCode)) {
                    result.setNotFoundOutRequestNo((String) i.get("not_found"));
                    List<CustomsDeclare> customsDeclareList = new ArrayList<>();
                    List<Map<String, Object>> list1 = (List<Map<String, Object>>) i.get("records");
                    list1.forEach(j -> {
                        List<Map<String, Object>> customs_declare = (List<Map<String, Object>>) j.get("customs_declare");
                        customs_declare.forEach(k -> {
                            CustomsDeclare cd = new CustomsDeclare();
                            cd.setOutRequestNo((String) k.get("out_request_no"));
                            cd.setDeclareNo((String) k.get("alipay_declare_no"));
                            cd.setTradeNo((String) k.get("trade_no"));
                            cd.setCustomsPlace((String) k.get("customs_place"));
                            cd.setMerchantCustomsNo((String) k.get("merchant_customs_code"));
                            cd.setMerchantCustomsName((String) k.get("merchant_customs_name"));
                            Double amount = Double.parseDouble((String) k.get("amount"));
                            cd.setAmount(amount.intValue() * 100);
                            cd.setIsSplit((String) k.get("is_split"));
                            cd.setSubOrderNo((String) k.get("sub_out_biz_no"));
                            cd.setApplyClearanceResultStatus((String) k.get("status"));
                            cd.setRemark((String) k.get("memo"));
                            cd.setLastModifyTime(UtilDate.parseDateTime((String) k.get("last_modified_time")));
                            cd.setCustomsCode((String) k.get("customs_code"));
                            cd.setCustomsInfo((String) k.get("customs_info"));
                            cd.setCustomsReturnTime(UtilDate.parseDateTimeLong((String) k.get("customs_return_time")));
                            customsDeclareList.add(cd);
                        });
                    });
//                    resultMap.put("customs_declare", customsDeclareList);
                    result.setDeclareList(customsDeclareList);
                } else {
                    result.setErrorCode((String) i.get("detail_error_code"));
                    result.setErrorMsg((String) i.get("detail_error_des"));
//                    resultMap.put("error_code", (String) i.get("detail_error_code"));
//                    resultMap.put("error_msg", (String) i.get("detail_error_des"));
                }
            });
        }
        if (TrueFalse.F.equalsIgnoreCase(isSuccess)) {
            result.setSuccess(Boolean.TRUE);
            String errorCode = (String) map.get("error");
            result.setErrorCode(errorCode);
            result.setErrorMsg(AlipayAppErrorCodeEnums.getErrorCodeEnum(errorCode).getDesc());
//            resultMap.put("error_code", errorCode);
//            resultMap.put("error_msg", AlipayAppErrorCodeEnums.getErrorCodeEnum(errorCode).getDesc());
        }
//        resultMap.put("is_success", isSuccess);
        return result;
    }
}
